package ca.cbc.msb.daemon;

import ca.cbc.msb.guice.MSBModule;
import ca.cbc.msb.util.AppConfig;

import com.google.inject.Guice;
import com.google.inject.Injector;
import org.apache.commons.daemon.Daemon;
import org.apache.commons.daemon.DaemonContext;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MSBDaemon implements Daemon {
    private static Logger logger = LoggerFactory.getLogger(MSBDaemon.class);

    private Main main;
    private SimpleDateFormat scheduleFormat = new SimpleDateFormat("hh:mm a");
    private SimpleDateFormat durationFormat = new SimpleDateFormat("mm:ss");
    private String yehCronExpression;
    private Scheduler schedule;
    private JobDetail yehJobDetail;
    private Trigger yehTrigger;

    @Override
    public final void init(DaemonContext daemonContext) {
        logger.debug("MSB Daemon initializing...");
        Injector injector = Guice.createInjector(new MSBModule());
        main = injector.getInstance(Main.class);

        SchedulerFactory schedFact = new StdSchedulerFactory();
        try {
            yehCronExpression = AppConfig.getProperty("yospace.expire.cron.expression");
            schedule = schedFact.getScheduler();
            yehJobDetail = new JobDetail("Yospace Expire Handler Job", null, YospaceExpireHandlerJob.class);
            yehTrigger = new CronTrigger("Yospace Expire Handler Trigger", null, yehCronExpression);

            schedule.scheduleJob(yehJobDetail, yehTrigger);
            schedule.addGlobalJobListener(new ParseJobListener());
        } catch (SchedulerException e) {
            logger.error("Error when init quartz scheduler...", e);
        } catch (ParseException e) {
        	logger.error("Error when init quartz scheduler...", e);
		}
    }

    @Override
    public final void start() {
        main.start();
        logger.info("MSB Daemon started...");

        try {
            logger.info("Yospace Expire Handler Daemon starting...");
            schedule.start();
            logger.info(yehJobDetail.getName() + " started at " + scheduleFormat.format(yehTrigger.getNextFireTime()));
        } catch (SchedulerException e) {
            logger.error("Error starting deamon...", e);
        }

        //start the monitor
//        MessageServer msgServer = new MessageServer();
//        msgServer.setBindPort(Integer.parseInt(AppConfig.getProperty("monitor.port")));
//        msgServer.run();
//        logger.info("MQ Monitor started on port {}...", msgServer.getBindPort());
    }

    @Override
    public final void stop() {
        try {
            logger.info("Yospace Expire Handler Daemon stopped...");
            schedule.shutdown();
        } catch (Exception e) {
            logger.error("Error stopping Scheduler...", e);
        }

        main.stop();
        logger.info("MSB Daemon stopped...");


    }

    @Override
    public final void destroy() {
        logger.info("MSB Daemon Destroyed");

    }

    class ParseJobListener implements JobListener {
        public String getName() {
            return "yospaceExpireHandler parse job listener";
        }

        public void jobExecutionVetoed(JobExecutionContext jobExCtx) {
            logger.info(jobExCtx.getJobDetail().getName() + " vetoed");
        }

        public void jobToBeExecuted(JobExecutionContext jobExCtx) {
            logger.info(jobExCtx.getJobDetail().getName() + " beggining parse process");
        }

        public void jobWasExecuted(JobExecutionContext jobExCtx, JobExecutionException jobExExc) {
            logger.info(jobExCtx.getJobDetail().getName() +
                    " finished parse process. Time to complete: " + durationFormat.format(new Date(jobExCtx.getJobRunTime())) +
                    ". Next job execution at " + scheduleFormat.format(jobExCtx.getNextFireTime()));
        }
    }
}
